﻿using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MQTTnet;
using MQTTnet.AspNetCore;
using MQTTnet.Internal;
using MQTTnet.Protocol;
using MQTTnet.Server;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JESAI.MQTT.Server.ServiceCollections
{
    public static class ServiceCollectionExtensions
    {

        public static void MapJESAIMqttServer(this IEndpointRouteBuilder endpoints, string pattern)
        {
            endpoints.MapConnectionHandler<MqttConnectionHandler>(pattern, options =>
            {
                options.WebSockets.SubProtocolSelector = MqttSubProtocolSelector.SelectSubProtocol;
            });
        }

        public static void UseJESAIMqttServer(this IApplicationBuilder app)
        {
            var Configuration = app.ApplicationServices.GetRequiredService<IConfiguration>();
            string username = Configuration["MqttServerOption:UserName"];//用户名
            string password = Configuration["MqttServerOption:Password"];//密码

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapMqtt("/mqtt");
            });

          
            app.UseMqttServer(server =>
            {
                //服务启动事件
                server.StartedAsync += async args =>
                {
                    Console.WriteLine("MQTT服务器启动");
                    var msg = new MqttApplicationMessageBuilder().WithPayload("welcome to mqtt").WithTopic("start");
                    while (true)
                    {
                        try
                        {
                            server.InterceptingPublishAsync += eventArgs =>
                            {
                                eventArgs.ApplicationMessage = msg.Build();
                                msg.WithPayload("you are welcome to mqtt");
                                return CompletedTask.Instance;
                            };
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e);
                        }
                        finally
                        {
                            await Task.Delay(TimeSpan.FromSeconds(5));
                        }
                    }
                };
                //服务停止事件
                server.StoppedAsync += args =>
                {
                    Console.WriteLine("---------------------------------------------------------------------------");
                    return Task.CompletedTask;
                };

                //客户端连接事件
                server.ClientConnectedAsync += args =>
                {
                    Console.WriteLine("---------------------------------------------------------------------------");
                    var clientId = args.ClientId;
                    return Task.CompletedTask;
                };
                //客户端断开事件
                server.ClientDisconnectedAsync += args =>
                {
                    Console.WriteLine("---------------------------------------------------------------------------");
                    var clientId = args.ClientId;
                    return Task.CompletedTask;
                };

                //校验连接
                server.ValidatingConnectionAsync += e =>
                {
                    Console.WriteLine("---------------------------------------------------------------------------");
                    if (e.ClientId == "SpecialClient")
                    {
                        if (e.UserName != username || e.Password != password)
                        {
                            e.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                        }
                    }
                    return CompletedTask.Instance;
                };
            });


            int hostPort = int.Parse(Configuration["MqttServerOption:HostPort"]);//端口号
            WebHost.CreateDefaultBuilder(new string[] { }).UseKestrel(o =>
            {
                o.ListenAnyIP(hostPort, m => m.UseMqtt());
            });
        }

        public static IServiceCollection AddJESAIMQTTServer(this IServiceCollection services, IConfiguration Configuration)
        {
            string hostIp = Configuration["MqttServerOption:HostIp"];//IP地址
            int hostPort = int.Parse(Configuration["MqttServerOption:HostPort"]);//端口号
            int timeout = int.Parse(Configuration["MqttServerOption:Timeout"]);//超时时间

            var optionBuilder = new MqttServerOptionsBuilder()
              .WithDefaultEndpointBoundIPAddress(System.Net.IPAddress.Parse(hostIp))
              .WithDefaultEndpointPort(hostPort)
              .WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(timeout));
            var option = optionBuilder.Build();
            //services.AddMqttServer();
            services
                .AddHostedMqttServer(option)
                .AddMqttConnectionHandler()
                .AddConnections();
            return services;
        }


    }
}
